#include "../../include/http/HttpContext.h"
using namespace muduo;
using namespace muduo::net;
namespace http
{
    // HttpContext构造函数
    // 初始化HTTP请求和响应的解析状态
    HttpContext::HttpContext()
    {
        // 设置请求解析状态为期待请求行状态
        _request_parse_state = ExpectRequestLine;
    }



    // 解析HTTP请求报文，将解析结果存储到HttpRequest对象中
    // 参数：buffer - 包含HTTP请求数据的缓冲区
    // 参数：receive_time - 接收请求的时间戳
    // 返回值：解析是否成功
    bool HttpContext::parseRequest(muduo::net::Buffer *buffer, muduo::Timestamp receive_time)
    {
        bool ok = true; // 标记解析是否成功

        // 循环处理缓冲区中的数据，直到没有更多输入或解析失败
        while (true)
        {
            // 解析请求行
            if (_request_parse_state == ExpectRequestLine)
            {
                const char *crlf = buffer->findCRLF();
                if (crlf)
                {
                    ok = processRequestLine(buffer->peek(), crlf);
                    if (ok)
                    {
                        _request.setReceiveTime(receive_time);
                        buffer->retrieveUntil(crlf + 2);
                        _request_parse_state = ExpectRequestHeaders;
                    }
                    else
                    {
                        return false; // 解析错误
                    }
                }
                else
                {
                    return ok; // 数据不完整，等待更多数据
                }
            }
            // 解析请求头
            else if (_request_parse_state == ExpectRequestHeaders)
            {
                const char *crlf = buffer->findCRLF();
                if (crlf)
                {
                    // 查找请求头中的冒号
                    const char *colon = std::find(buffer->peek(), crlf, ':');

                    if (colon < crlf)
                    {
                        // 找到冒号，这是一个有效的请求头行
                        _request.addHeader(buffer->peek(), colon, crlf);
                    }
                    else if (buffer->peek() == crlf)
                    {
                        // 遇到空行，表示请求头部分结束
                        _request_parse_state = ExpectRequestBody;
                    }
                    else
                    {
                        // 没有找到冒号且不是空行，格式错误
                        return false;
                    }

                    // 统一删除当前行数据
                    buffer->retrieveUntil(crlf + 2);
                }
                else
                {
                    return ok; // 数据不完整，等待更多数据
                }
            }
            // 解析请求体
            else if (_request_parse_state == ExpectRequestBody)
            {
                // 对于POST/PUT请求，需要解析请求体
                if (_request.getMethod() == HttpRequest::Put || _request.getMethod() == HttpRequest::Post)
                {
                    std::string contentLengthStr = _request.getHeader("Content-Length");
                    if (!contentLengthStr.empty())
                    {
                        // 如果转换失败，抛出异常
                        try
                        {
                            // 将Content-Length转换为整数
                            size_t contentLength = std::stoul(contentLengthStr);
                            // 设置请求体长度
                            _request.setContentLength(contentLength);

                            // 检查缓冲区中是否有足够的数据
                            if (buffer->readableBytes() >= contentLength)
                            {
                                // 读取指定长度的请求体数据
                                _request.setContent(buffer->peek(), buffer->peek() + contentLength);
                                // 精确移除已读取的数据
                                buffer->retrieve(contentLength);
                                // 标记解析完成
                                _request_parse_state = ExpectRequestComplete;
                                return true; // 解析完成
                            }
                            else
                            {
                                return ok; // 数据不够，等待更多数据
                            }
                        }
                        catch (const std::exception &e)
                        {
                            // 如果转换失败，抛出异常
                            return false; // Content-Length格式错误
                        }
                    }
                    else
                    {
                        return false; // POST/PUT 请求没有 Content-Length，HTTP语法错误
                    }
                }
                else
                {
                    // GET/HEAD/DELETE 等方法没有请求体，直接完成
                    _request_parse_state = ExpectRequestComplete;
                    return true;
                }
            }
            else
            {
                // 解析完成或未知状态
                return ok;
            }
        }
    }

    // 处理HTTP请求行的解析
    // 请求行格式：方法 URL(路径 ? 查询参数) 版本\r\n （如：GET /index.html HTTP/1.1\r\n）
    // 参数：begin - 请求行开始位置
    // 参数：end - 请求行结束位置
    // 返回值：解析是否成功
    bool HttpContext::processRequestLine(const char *begin, const char *end)
    {
        bool succeed = false;      // 标记解析是否成功
        const char *start = begin; // 记录当前解析位置

        // 检查输入有效性
        if (begin >= end)
        {
            return false;
        }

        // 查找第一个空格，用于分隔HTTP方法和URL
        const char *space = std::find(start, end, ' ');

        // 如果找到了空格,将请求方式记录下来
        if (space != end && _request.setMethod(start, space))
        {
            start = space + 1;

            // 检查是否还有剩余数据
            if (start >= end)
            {
                return false;
            }

            // 继续查找下一个空格，用于分隔URL路径和HTTP版本
            space = std::find(start, end, ' ');
            // 如果找到了空格（说明格式可能正确）
            if (space != end)
            {
                // 查找问号，用于分隔URL路径和查询参数
                const char *question = std::find(start, space, '?');
                // 如果找到了问号（说明有查询参数）
                if (question != space)
                {
                    // 设置URL路径
                    _request.setPath(start, question);
                    // 设置查询参数
                    _request.setQuery(question + 1, space);
                }
                else // 请求不带参数
                {
                    _request.setPath(start, space);
                }

                // 移动到HTTP版本的开始位置
                start = space + 1;

                succeed = ((end - start) == 8 && std::equal(start, start + 8, "HTTP/1."));
                if (succeed)
                {
                    if (*(end - 1) == '0')
                    {
                        _request.setVersion("HTTP/1.0");
                    }
                    else if (*(end - 1) == '1')
                    {
                        _request.setVersion("HTTP/1.1");
                    }
                    else
                    {
                        succeed = false;
                    }
                }
            }
        }
        return succeed;
    }
    void HttpContext::reset()
    {
        _request_parse_state = ExpectRequestLine;
        HttpRequest dummy;
        _request.swap(dummy);
    }
}
